//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;

namespace OpenLS.Spreadsheet.Expressions
{
    internal class CellReferenceExpression : CellEnumeratorExpression
    {
        private readonly Worksheet _caller;
        private readonly CellReference _cellReference;

        public CellReferenceExpression(CellReference cellRef, Worksheet caller)
        {
            Contract.Requires(cellRef != null);
            _cellReference = cellRef;
            _caller = caller;
        }
        public override string ToString()
        {
            return string.Format("{0} from {1}", _cellReference, _caller);
        }
        internal override Expression Transposed(Cell target)
        {
            return new CellReferenceExpression(_cellReference.Transposed(target), Caller)
                ;
        }


        public CellReference CellReference
        {
            get { return _cellReference; }
        }

        public Worksheet Caller
        {
            get { return _caller; }
        }

        protected override object GetValueAsTop(EvaluationContext context)
        {
            var cellAddress = CellReference.GetCellAddress(context);
            var cell = CellReference.GetCell(context);
            if (cellAddress != cell.Address)
                return 0d;
         //\\   if (Cell(context).Value == null)
           //\\     return 0d;
            return base.GetValue(context);
        }

        internal Cell Cell(EvaluationContext context)
        {
            Contract.Requires(context != null);
            Cell result = CellReference.GetCell(context);
            return result;
        }

        public override Expression Offset(CellRelativeAddress a)
        {
            return new CellReferenceExpression(CellReference.Offset(a), Caller);
        }

        public override string GetText(TextContext context)
        {
            if (Caller != CellReference.Worksheet)
                return CellReference.Worksheet.SafeName + "!" + _cellReference.GetText(context);
            return CellReference.GetText(context);
        }

        public override IEnumerable<Expression> GetSubExpressions()
        {
            yield break;
        }

        public override IEnumerable<IDependencyNode> GetPrecedents(EvaluationContext context) //\\OK
        {
            yield return Cell(context);
        }

        protected internal override ICellEnumerator GetCellsValue(EvaluationContext context)
        {
            Contract.Requires(context != null);
            return Cell(context);
        }

        public override Worksheet Worksheet
        {
            get { return CellReference.Worksheet; }
        }
    }
}